import * as vscode from 'vscode';
import * as path from 'path';
import { getWebviewContent } from './webview';
import { analyzeDependencies, initializeAnalyzer } from './analyzer';

let performanceStatusBarItem: vscode.StatusBarItem;

export function activate(context: vscode.ExtensionContext) {
    initializeAnalyzer(context);

    // Create a status bar item
    performanceStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
    context.subscriptions.push(performanceStatusBarItem);

    async function showGraph(uri: vscode.Uri) {
        const entryPoint = uri.fsPath;

        const panel = vscode.window.createWebviewPanel(
            'dependencyGraph',
            `Code Spider: ${path.basename(uri.fsPath)}`,
            vscode.ViewColumn.One,
            {
                enableScripts: true,
                localResourceRoots: [vscode.Uri.joinPath(context.extensionUri, 'media')],
                retainContextWhenHidden: true,
            }
        );

        const d3Uri = panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, 'media', 'd3.min.js'));
        const nonce = getNonce();
        panel.webview.html = getWebviewContent(nonce, d3Uri.toString());

        await vscode.window.withProgress(
            {
                location: vscode.ProgressLocation.Notification,
                title: 'Code Spider Analyzing Dependencies...',
                cancellable: false,
            },
            async (progress) => {
                try {
                    const config = vscode.workspace.getConfiguration('code-spider');
                    const analysisResult = await analyzeDependencies(entryPoint, {
                        include: config.get<string[]>('include'),
                        exclude: config.get<string[]>('exclude'),
                    });
                    if (analysisResult && analysisResult.d3Data) {
                        panel.webview.postMessage(analysisResult.d3Data);

                        performanceStatusBarItem.text = `$(graph) ${analysisResult.stats.nodeCount} nodes in ${analysisResult.stats.analysisTime}ms`;
                        performanceStatusBarItem.show();
                    }
                } catch (error: any) {
                    vscode.window.showErrorMessage(`Failed to analyze dependencies: ${error.message}`);
                }
            }
        );
        
        panel.webview.onDidReceiveMessage(
            async message => {
                switch (message.command) {
                    case 'openFile':
                        const filePath = message.path;
                        if (filePath) {
                            vscode.workspace.openTextDocument(vscode.Uri.file(filePath)).then(doc => {
                                vscode.window.showTextDocument(doc, { preview: false });
                            });
                        }
                        return;
                }
            },
            undefined,
            context.subscriptions
        );
    }

    function getProjectRoot(entryPoint: string): string | undefined {
        const dir = path.dirname(entryPoint);
        const root = vscode.workspace.workspaceFolders?.find((folder) => dir.startsWith(folder.uri.fsPath));
        return root?.uri.fsPath;
    }

    const showGraphDisposable = vscode.commands.registerCommand('code-spider.showGraph', (uri?: vscode.Uri) => {
        if (uri) {
            showGraph(uri);
        } else if (vscode.window.activeTextEditor) {
            showGraph(vscode.window.activeTextEditor.document.uri);
        } else {
            vscode.window.showInformationMessage('Please select a file to show its dependency graph.');
        }
    });

    const clearCacheDisposable = vscode.commands.registerCommand('code-spider.clearCache', () => {
        context.workspaceState.keys().forEach(key => {
            context.workspaceState.update(key, undefined);
        });
        vscode.window.showInformationMessage('Code Spider cache has been cleared.');
    });

    const showGraphWithParamsDisposable = vscode.commands.registerCommand('code-spider.showGraphWithParams', (args) => {
        vscode.window.showInformationMessage(`Command executed with args: ${JSON.stringify(args)}`);
        const activeEditor = vscode.window.activeTextEditor;
        if (activeEditor) {
            showGraph(activeEditor.document.uri);
        } else {
            vscode.window.showInformationMessage('Please open a file to show its dependency graph.');
        }
    });

    context.subscriptions.push(showGraphDisposable, clearCacheDisposable, showGraphWithParamsDisposable);
}

function getNonce() {
    let text = '';
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < 32; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }
    return text;
}

export function deactivate() {}